/**jsonFormat 格式化json数据，解决后端fastJson序列化循环引用的数据，逐步解决中 */

function format(data, json) {
  for (var item in json) {
    //遍历对象中的属性，只显示出非函数的属性
    if (typeof (json[item]) == "function")
      continue;
    else if (json[item] instanceof Array) {
      this.format(data, json[item]);
    } else if (typeof json[item] == "object") {
      if (json[item].hasOwnProperty("$ref")) {
        var path = json[item]["$ref"].split(".");
        json[item] = getProperty(data, path);
      }
      else
        this.format(data, json[item]);
    }
  }
}

//获取值
function getProperty(data, path) {
  //var result = cloneObj(data);  //不用克隆
  var result = data;
  var reg = /\[(\d+)\]/;
  for (var i = 1; i < path.length; i++) {
    if (reg.test(path[i])) {
      var flag = path[i].split(/\[(\d+)\]/);
      result = result[flag[0]][flag[1]];
    } else {
      result = result[path[i]];
    }
  }
  return result;
}

//克隆对象
function cloneObj(obj) {
  var newObj = {};
  if (obj instanceof Array) {
    newObj = [];
  }
  for (var key in obj) {
    var val = obj[key];
    newObj[key] = typeof val === 'object' ? cloneObj(val) : val;
  }
  return newObj;
}

/** 对比两个对象是否相等 */
function compareObj(x,y){
  if (x === y) {
    return true;
  }

  // If they are not strictly equal, they both need to be Objects  
  if (!(x instanceof Object) || !(y instanceof Object)) {
    return false;
  }

  for (var p in x) {
    // Inherited properties were tested using x.constructor === y.constructor  
    if (x.hasOwnProperty(p)) {
      // Allows comparing x[ p ] and y[ p ] when set to undefined  
      if (!y.hasOwnProperty(p)) {
        return false;
      }
      // If they have the same strict value or identity then they are equal  
      if (x[p] === y[p]) {
        continue;
      }
      // Numbers, Strings, Functions, Booleans must be strictly equal  
      if (typeof (x[p]) !== "object") {
        return false;
      }
      // Objects and Arrays must be tested recursively  
      if (!Object.equals(x[p], y[p])) {
        return false;
      }
    }
  }

  for (p in y) {
    // allows x[ p ] to be set to undefined  
    if (y.hasOwnProperty(p) && !x.hasOwnProperty(p)) {
      return false;
    }
  }
  return true;  
}

module.exports = {
  format: format,
  cloneObj: cloneObj,
  compareObj: compareObj
}